///
/// AEye, Inc. ("COMPANY") CONFIDENTIAL
/// Unpublished Copyright (c) 2013-2023 AEye, Inc., All Rights Reserved.
///
/// NOTICE:  All information contained herein is, and remains the property of COMPANY.
/// The intellectual and technical concepts contained herein are proprietary to COMPANY and
/// may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law.
/// Dissemination of this information or reproduction of this material is strictly forbidden unless
/// prior written permission is obtained from COMPANY.
/// Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, managers,
/// or contractors who have executed Confidentiality and Non-disclosure agreements explicitly covering such access.
///
/// The copyright notice above does not evidence any actual or intended publication or disclosure of this source code,
/// which includes information that is confidential and/or proprietary, and is a trade secret, of  COMPANY.
/// ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS
/// SOURCE CODE WITHOUT THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE
/// LAWS AND INTERNATIONAL TREATIES. THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION DOES NOT
/// CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE, OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL
/// ANYTHING THAT IT  MAY DESCRIBE, IN WHOLE OR IN PART.
///

#ifndef POINTSTRUCTURE_HPP
#define POINTSTRUCTURE_HPP

#include <cstdint>

#ifdef _MSC_VER
#define ATTRIBUTE_PACKED
#else
#define ATTRIBUTE_PACKED __attribute__((__packed__))
#endif

namespace aeye {

  /// @enum PointReturnFlags
  /// @brief bit masks corresponding to what kind of data to get from the sensor
  /// @sa
  enum PointReturnFlags : uint16_t {
      UNUSED_0              = 0x0001,
      SPHERICAL_COORDINATES = 0x0002,
      UNUSED_1              = 0x0004,
      INTENSITY             = 0x0008,
      UNUSED_2              = 0x0010,
      UNUSED_3              = 0x0020,
      UNUSED_4              = 0x0040,
      UNUSED_5              = 0x0080,
      UNUSED_6              = 0X0100,
      UNUSED_7              = 0x0200,
      UNUSED_8              = 0x0400,
  };

#ifdef _MSC_VER
#pragma pack(push,1)
#endif

  /// @typedef Cartesian Point
  typedef struct {
    float  x; ///< (meters) Distance along the axis looking out the barrel of the sensor. (Front)
    float  y; ///< (meters) Distance along the axis which is neither x nor z. (Left)
    float  z; ///< (meters) Distance along the vertical axis. (Up)
  } ATTRIBUTE_PACKED PointReturnCartesianCoords;

  /// @typedef Point Spherical Data
  typedef struct {
    int16_t azimuth;      ///< (10000ths of a radian) Right (-y) is positive (left-handed).
    int16_t elevation;    ///<  (10000ths of a radian) Up (+z) is positive.
    uint16_t  radius_scaled;       ///< (meters) Distance from sensor to point.
  } ATTRIBUTE_PACKED PointReturnSphericalCoords;

  /// @typedef Point Unused_1 Data
  typedef struct {
    uint16_t reserved1;
    uint16_t reserved2;
    uint8_t  flags;
  } ATTRIBUTE_PACKED PointReturnUnused_1;

  /// @typedef Point Intensity Data
  typedef struct {
    uint16_t intensity_type_data;       ///< [0, 65535] Scaled energy of light received, set by configuration intensity_return_type
  } ATTRIBUTE_PACKED PointReturnIntensity;

  /// @typedef Point Unused_8 Data
  typedef struct {
      uint8_t reserved1;
      uint8_t reserved2;
  } ATTRIBUTE_PACKED PointReturnUnused_8;

  /// @typedef Point Unused_2 Data
  typedef struct {
    uint32_t reserved1;
  } ATTRIBUTE_PACKED PointReturnUnused_2;

  /// @typedef Point Unused_3 Data
  typedef struct {
    uint16_t reserved1;
    uint16_t reserved2;
  } ATTRIBUTE_PACKED PointReturnUnused_3;

  /// @typedef Point Unused_4 Data
  typedef struct {
    uint16_t reserved1;
    uint16_t reserved2;
  } ATTRIBUTE_PACKED PointReturnUnused_4;

  /// @typedef Receiver Unused_5 Data
  typedef struct {
    uint16_t reserved1;
    uint16_t reserved2;
  } ATTRIBUTE_PACKED PointReturnUnused_5;

  /// @typedef Receiver Unused_6 Data
  typedef struct {
    uint8_t  reserved1;
    uint8_t  reserved2;
    uint8_t  reserved3;
  } ATTRIBUTE_PACKED PointReturnUnused_6;
  /// @endcond

  /// @typedef Point Type Return Mask
  typedef struct {
    uint8_t  point_return_mask; ///< Selected Point Cloud Data Menu Items
  } ATTRIBUTE_PACKED PointReturnType;

  /// @typedef Point Unused_7 Debug
  typedef struct {
    uint32_t  reserved1;
  } ATTRIBUTE_PACKED PointReturnUnused_7;

#ifdef _MSC_VER
#pragma pack(pop)
#endif

  /// @typedef Combined Point Return Structure
  typedef struct {
    PointReturnCartesianCoords pointReturnCartesianCoords;
    PointReturnSphericalCoords pointReturnSphericalCoords;
    PointReturnUnused_1        pointReturnUnused_1;
    PointReturnIntensity       pointReturnIntensity;
    PointReturnUnused_8        pointReturnUnused_8;
    PointReturnUnused_2        pointReturnUnused_2;
    PointReturnUnused_3        pointReturnUnused_3;
    PointReturnUnused_4        pointReturnUnused_4;
    PointReturnUnused_5        pointReturnUnused_5;
    PointReturnUnused_6        pointReturnUnused_6;
    PointReturnType            pointReturnType;
    PointReturnUnused_7        pointReturnUnused_7;
  } AEyePoint;
}

#endif //POINTSTRUCTURE_HPP